//package com.lord.pay.unionpay.utils;
//
//import java.util.HashMap;
//import java.util.Map;
//
//import com.lord.pay.unionpay.sdk.AcpService;
//import com.lord.pay.unionpay.sdk.DemoBase;
//import com.lord.pay.unionpay.sdk.LogUtil;
//import com.lord.pay.unionpay.sdk.SDKConfig;
//
///**
// * @Description: 自定义封装的常用银联支付方法
// * @author Lord
// * @date 2019年8月28日
// */
//public class UnionpayUtils {
//
//    public static final String MERID = "777290058110097";
//
//    /**
//     * 产品：代收产品<br>
//     * 交易：查询卡开通状态：后台交易，无通知<br>
//     * @param cardNo 银行卡号
//     * @param orderCode 订单号
//     * @param txnTime 当初交易时，订单的发送时间
//     * @return
//     * @throws Exception
//     */
//    public static Map<String, String> merchantOpenQuery(String cardNo, String orderCode, String txnTime)
//            throws Exception {
//        Map<String, String> contentData = new HashMap<>(16);
//
//        /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
//        contentData.put("version", DemoBase.version); // 版本号
//        contentData.put("encoding", DemoBase.encoding); // 字符集编码 可以使用UTF-8,GBK两种方式
//        contentData.put("signMethod", SDKConfig.getConfig().getSignMethod()); // 签名方法
//        contentData.put("txnType", "78"); // 交易类型 78-开通查询
//        contentData.put("txnSubType", "00"); // 交易子类型 00-根据账号accNo查询(默认）
//        contentData.put("bizType", "000301"); // 业务类型 认证支付2.0
//        contentData.put("channelType", "07"); // 渠道类型07-PC
//
//        /***商户接入参数***/
//        contentData.put("merId", MERID); // 商户号码，请改成自己申请的商户号或者open上注册得来的777商户号测试
//        contentData.put("accessType", "0"); // 接入类型，商户接入固定填0，不需修改
//
//        /***要调通交易以下字段必须修改***/
//        contentData.put("orderId", orderCode); // ****商户订单号，每次发交易测试需修改为被查询的交易的订单号
//        contentData.put("txnTime", txnTime); // ****订单发送时间，每次发交易测试需修改为被查询的交易的订单发送时间
//
//        //////////// 如果商户号开通了【商户对敏感信息加密】的权限那么需要对 accNo,phoneNo加密使用：
//        String accNo1 = AcpService.encryptData(cardNo, DemoBase.encoding); // 这里测试的时候使用的是测试卡号，正式环境请使用真实卡号
//        contentData.put("accNo", accNo1);
//        contentData.put("encryptCertId", AcpService.getEncryptCertId()); // 加密证书的certId，配置在acp_sdk.properties文件
//                                                                         // acpsdk.encryptCert.path属性下
//
//        /**对请求参数进行签名并发送http post请求，接收同步应答报文**/
//        Map<String, String> reqData = AcpService.sign(contentData, DemoBase.encoding); // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
//        String requestBackUrl = SDKConfig.getConfig().getBackRequestUrl(); // 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
//                                                                           // acpsdk.backTransUrl
//        Map<String, String> rspData = AcpService.post(reqData, requestBackUrl, DemoBase.encoding); // 发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过
//
//        /**对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**/
//        // 应答码规范参考open.unionpay.com帮助中心 下载 产品接口规范 《平台接入接口规范-第5部分-附录》
//        if (!rspData.isEmpty()) {
//            if (AcpService.validate(rspData, DemoBase.encoding)) {
//                LogUtil.writeLog("----查询卡开通状态--验证签名成功");
//                if ("00".equals(rspData.get("respCode"))) {
//                    // 处理被查询交易的应答码逻辑
//                    String respCode = rspData.get("respCode");
//                    if ("00".equals(respCode)) {
//                        String customerInfo = rspData.get("customerInfo");
//                        if (null != customerInfo) {
//                            // return AcpService.parseCustomerInfo(customerInfo, DemoBase.encoding);
//                            return rspData;
//                        }
//                    } else if ("03".equals(respCode) || "04".equals(respCode) || "05".equals(respCode)) {
//                        // 需再次发起查询卡开通状态
//                        LogUtil.writeLog("------需再次发起查询卡开通状态");
//                        return merchantOpenQuery(cardNo, orderCode, txnTime);
//                    } else {
//                        // 其他应答码为失败请排查原因
//                        LogUtil.writeLog("------其他应答码为失败请排查原因");
//                        return null;
//                    }
//                } else {// 查询交易本身失败，或者未查到原交易，检查查询交易报文要素
//                    LogUtil.writeLog("------查询交易本身失败，或者未查到原交易，检查查询交易报文要素");
//                    return null;
//                }
//            } else {
//                LogUtil.writeErrorLog("查询交易接口，验证签名失败");
//                return null;
//            }
//        } else {
//            // 未返回正确的http状态
//            LogUtil.writeErrorLog("查询交易接口，未获取到返回报文或返回http状态码非200");
//            return null;
//        }
//        return null;
//    }
//
//    /**
//     * 产品：无跳转产品<br>
//     * 交易：商户侧开通：后台交易，无通知<br>
//     * @param cardNo 银行卡号
//     * @param orderCode 订单号
//     * @param txnTime 当初交易时，订单的发送时间
//     * @return
//     * @throws Exception
//     */
//    public static Map<String, String> merchantOpenCard(String cardNo, String orderCode, String txnTime)
//            throws Exception {
//        Map<String, String> contentData = new HashMap<>(16);
//
//        /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
//        contentData.put("version", DemoBase.version); // 版本号
//        contentData.put("encoding", DemoBase.encoding); // 字符集编码 可以使用UTF-8,GBK两种方式
//        contentData.put("signMethod", SDKConfig.getConfig().getSignMethod()); // 签名方法
//        contentData.put("txnType", "79"); // 交易类型 11-代收
//        contentData.put("txnSubType", "00"); // 交易子类型 00-默认开通
//        contentData.put("bizType", "000301"); // 业务类型 认证支付2.0
//        contentData.put("channelType", "07"); // 渠道类型07-PC
//
//        /***商户接入参数***/
//        contentData.put("merId", MERID); // 商户号码（本商户号码仅做为测试调通交易使用，该商户号配置了需要对敏感信息加密）测试时请改成自己申请的商户号，【自己注册的测试777开头的商户号不支持代收产品】
//        contentData.put("accessType", "0"); // 接入类型，商户接入固定填0，不需修改
//        contentData.put("orderId", orderCode); // 商户订单号，如上送短信验证码，请填写获取验证码时一样的orderId，此处默认取demo演示页面传递的参数
//        contentData.put("txnTime", txnTime); // 订单发送时间，如上送短信验证码，请填写获取验证码时一样的txnTime，此处默认取demo演示页面传递的参数
//        contentData.put("accType", "01"); // 账号类型，01：借记账户，02：贷记账户
//
//        // 贷记卡 必送：卡号、手机号、CVN2、有效期；验证码看业务配置（默认不要短信验证码）。
//        // 借记卡 必送：卡号、手机号；选送：证件类型+证件号、姓名；验证码看业务配置（默认不要短信验证码）。
//        // 此测试商户号777290058110097 后台开通业务只支持 贷记卡
//        Map<String, String> customerInfoMap = new HashMap<String, String>();
//        // customerInfoMap.put("certifTp", "01"); //证件类型，01：身份证，02：军官证，03：护照，04：港澳证，05：台胞证，06：警官证，07：士兵证，99：其他证件
//        // customerInfoMap.put("certifId", "341126197709218366"); //证件号码
//        // customerInfoMap.put("customerNm", "全渠道"); //姓名
//        customerInfoMap.put("phoneNo", "13552535506"); // 手机号
//        // customerInfoMap.put("pin", "123456"); //密码【这里如果送密码 商户号必须配置 ”商户允许采集密码“】
//        customerInfoMap.put("cvn2", "123"); // 卡背面的cvn2三位数字
//        customerInfoMap.put("expired", "2311"); // 有效期 年在前月在后
//        customerInfoMap.put("smsCode", "111111"); // 短信验证码
//
//        //////////// 如果商户号开通了【商户对敏感信息加密】的权限那么需要对 accNo，pin和phoneNo，cvn2，expired加密（如果这些上送的话），对敏感信息加密使用：
//        String accNo1 = AcpService.encryptData(cardNo, DemoBase.encoding); // 这里测试的时候使用的是测试卡号，正式环境请使用真实卡号
//        contentData.put("accNo", accNo1);
//        contentData.put("encryptCertId", AcpService.getEncryptCertId()); // 加密证书的certId，配置在acp_sdk.properties文件
//                                                                         // acpsdk.encryptCert.path属性下
//        String customerInfoStr = AcpService.getCustomerInfoWithEncrypt(customerInfoMap, null, DemoBase.encoding);
//        //////////
//
//        contentData.put("customerInfo", customerInfoStr);
//        // contentData.put("reqReserved", "透传字段");
//        // //请求方保留域，透传字段（可以实现商户自定义参数的追踪）本交易的后台通知,对本交易的交易状态查询交易、对账文件中均会原样返回，商户可以按需上传，长度为1-1024个字节。出现&={}[]符号时可能导致查询接口应答报文解析失败，建议尽量只传字母数字并使用|分割，或者可以最外层做一次base64编码(base64编码之后出现的等号不会导致解析失败可以不用管)。
//
//        /**对请求参数进行签名并发送http post请求，接收同步应答报文**/
//        Map<String, String> reqData = AcpService.sign(contentData, DemoBase.encoding); // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
//        String requestBackUrl = SDKConfig.getConfig().getBackRequestUrl(); // 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
//                                                                           // acpsdk.backTransUrl
//        Map<String, String> rspData = AcpService.post(reqData, requestBackUrl, DemoBase.encoding);
//
//        /**对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**/
//        // 应答码规范参考open.unionpay.com帮助中心 下载 产品接口规范 《平台接入接口规范-第5部分-附录》
//        if (!rspData.isEmpty()) {
//            if (AcpService.validate(rspData, DemoBase.encoding)) {
//                LogUtil.writeLog("----商户侧开卡--验证签名成功");
//                if ("00".equals(rspData.get("respCode"))) {
//                    // 处理被开卡的应答码逻辑
//                    String respCode = rspData.get("respCode");
//                    if ("00".equals(respCode)) {
//                        return rspData;
//                    } else if ("03".equals(respCode) || "04".equals(respCode) || "05".equals(respCode)) {
//                        // 需再次发起商户侧开卡
//                        LogUtil.writeLog("------需再次发起商户侧开卡");
//                        return merchantOpenCard(cardNo, orderCode, txnTime);
//                    } else {
//                        // 其他应答码为失败请排查原因
//                        LogUtil.writeLog("------其他应答码为失败请排查原因");
//                        return null;
//                    }
//                } else {// 查询交易本身失败，或者未查到原交易，检查查询交易报文要素
//                    LogUtil.writeLog("------查询交易本身失败，或者未查到原交易，检查查询交易报文要素");
//                    return null;
//                }
//            } else {
//                LogUtil.writeErrorLog("查询交易接口，验证签名失败");
//                return null;
//            }
//        } else {
//            // 未返回正确的http状态
//            LogUtil.writeErrorLog("查询交易接口，未获取到返回报文或返回http状态码非200");
//            return null;
//        }
//    }
//
//    /**
//     * 提交银联前台交易接口
//     * @param paySerialCode 银联支付流水号
//     * @param payAmount 支付金额
//     * @param payCardNo 支付指定使用的卡号，且不能修改，为空则不指定
//     * @param frontUrl 前台通知地址 （需设置为外网能访问 http https均可），支付成功后的页面 点击“返回商户”按钮的时候将异步通知报文post到该地址，此处指的是除去域名的相对路径，如：/myOrder
//     * @param backUrl 后台通知地址（需设置为【外网】能访问 http https均可），支付成功后银联会自动将异步通知报文post到商户上送的该地址，失败的交易银联不会发送后台通知，此处指的是除去域名的相对路径，如：/amp/h5/order/unionpayBack
//     */
//    // public static String submitFrontConsume(String paySerialCode, BigDecimal payAmount, String payCardNo,
//    // String frontUrl, String backUrl) throws Exception {
//    // Map<String, String> requestData = new HashMap<String, String>();
//    //
//    // /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
//    // requestData.put("version", SDKConfig.getConfig().getVersion()); // 版本号，全渠道默认值
//    // requestData.put("encoding", SDKConfig.getConfig().getEncoding()); // 字符集编码，可以使用UTF-8,GBK两种方式
//    // requestData.put("signMethod", SDKConfig.getConfig().getSignMethod()); // 签名方法
//    // requestData.put("txnType", "01"); // 交易类型 ，01：消费
//    // requestData.put("txnSubType", "01"); // 交易子类型， 01：自助消费
//    // requestData.put("bizType", "000201"); // 业务类型，B2C网关支付，手机wap支付
//    // requestData.put("channelType", "07"); // 渠道类型，这个字段区分B2C网关支付和手机wap支付；07：PC,平板 08：手机
//    //
//    // /***商户接入参数***/
//    // requestData.put("merId", SDKConfig.getConfig().getMerId()); // 商户号码，请改成自己申请的正式商户号或者open上注册得来的777测试商户号
//    // requestData.put("accessType", "0"); // 接入类型，0：直连商户
//    // requestData.put("orderId", paySerialCode); // 商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则
//    // requestData.put("txnTime", DateUtil.date2Str(new Date(), "yyyyMMddHHmmss")); //
//    // 订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
//    // requestData.put("currencyCode", "156"); // 交易币种（境内商户一般是156 人民币）
//    // requestData.put("txnAmt", CalcUtil.mul(payAmount, new BigDecimal("100"), 0).toString()); // 交易金额，单位分，不要带小数点
//    // // requestData.put("reqReserved", "透传字段");
//    // //
//    // //请求方保留域，如需使用请启用即可；透传字段（可以实现商户自定义参数的追踪）本交易的后台通知,对本交易的交易状态查询交易、对账文件中均会原样返回，商户可以按需上传，长度为1-1024个字节。出现&={}[]符号时可能导致查询接口应答报文解析失败，建议尽量只传字母数字并使用|分割，或者可以最外层做一次base64编码(base64编码之后出现的等号不会导致解析失败可以不用管)。
//    // // requestData.put("riskRateInfo", "{commodityName=测试商品名称}");
//    // if (payCardNo != null && payCardNo.length() > 0) {
//    // requestData.put("accNo", payCardNo); // 需锁定的支付卡号，商户直接上送卡号并在银联页面锁定该卡号支付（送accNo时会默认填上这个卡号，用户不能修改支付卡）
//    // }
//    //
//    // // 前台通知地址 （需设置为外网能访问 http https均可），支付成功后的页面 点击“返回商户”按钮的时候将异步通知报文post到该地址
//    // // 如果想要实现过几秒中自动跳转回商户页面权限，需联系银联业务申请开通自动返回商户权限
//    // // 异步通知参数详见open.unionpay.com帮助中心 下载 产品接口规范 网关支付产品接口规范 消费交易 商户通知
//    // requestData.put("frontUrl", YmlProps.httpServerUrl + frontUrl);
//    //
//    // // 后台通知地址（需设置为【外网】能访问 http https均可），支付成功后银联会自动将异步通知报文post到商户上送的该地址，失败的交易银联不会发送后台通知
//    // // 后台通知参数详见open.unionpay.com帮助中心 下载 产品接口规范 网关支付产品接口规范 消费交易 商户通知
//    // // 注意:1.需设置为外网能访问，否则收不到通知 2.http https均可 3.收单后台通知后需要10秒内返回http200或302状态码
//    // // 4.如果银联通知服务器发送通知后10秒内未收到返回状态码或者应答码非http200，那么银联会间隔一段时间再次发送。总共发送5次，每次的间隔时间为0,1,2,4分钟。
//    // // 5.后台通知地址如果上送了带有？的参数，例如：http://abc/web?a=b&c=d 在后台通知处理程序验证签名之前需要编写逻辑将这些字段去掉再验签，否则将会验签失败
//    // requestData.put("backUrl", YmlProps.httpServerUrl + backUrl);
//    //
//    // // 订单超时时间。超过此时间后，除网银交易外，其他交易银联系统会拒绝受理，提示超时。
//    // // 跳转银行网银交易如果超时后交易成功，会自动退款，大约5个工作日金额返还到持卡人账户。此时间建议取支付时的北京时间加15分钟。超过超时时间调查询接口应答origRespCode不是A6或者00的就可以判断为失败。
//    // requestData.put("payTimeout",
//    // new SimpleDateFormat("yyyyMMddHHmmss").format(new Date().getTime() + 15 * 60 * 1000));
//    //
//    // /**请求参数设置完毕，以下对请求参数进行签名并生成html表单，将表单写入浏览器跳转打开银联页面**/
//    // Map<String, String> submitFromData = AcpService.sign(requestData, SDKConfig.getConfig().getEncoding()); //
//    // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
//    //
//    // String requestFrontUrl = SDKConfig.getConfig().getFrontRequestUrl(); //
//    // 获取请求银联的前台地址：对应属性文件acp_sdk.properties文件中的acpsdk.frontTransUrl
//    // String html = AcpService.createAutoFormHtml(requestFrontUrl, submitFromData,
//    // SDKConfig.getConfig().getEncoding()); // 生成自动跳转的Html表单
//    //
//    // LogUtil.writeLog("打印请求HTML，此为请求报文，为联调排查问题的依据：" + html);
//    // return html;
//    //
//    // // 将生成的html写到浏览器中完成自动跳转打开银联支付页面；这里调用signData之后，将html写到浏览器跳转到银联页面之前均不能对html中的表单项的名称和值进行修改，如果修改会导致验签不通过
//    // // PrintWriter out = response.getWriter();
//    // // out.write(html);
//    // // out.flush();
//    // // out.close();
//    // }
//    //
//    // /**
//    // * 银联交易查询接口
//    // * @param paySerialCode 银联支付流水号
//    // * @param txnTime 当初交易时，订单的发送时间
//    // * @return
//    // * @throws Exception
//    // */
//    // public static Map<String, String> consumeQuery(String paySerialCode, String txnTime) throws Exception {
//    // Map<String, String> data = new HashMap<String, String>();
//    //
//    // /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
//    // data.put("version", SDKConfig.getConfig().getVersion()); // 版本号
//    // data.put("encoding", SDKConfig.getConfig().getEncoding()); // 字符集编码 可以使用UTF-8,GBK两种方式
//    // data.put("signMethod", SDKConfig.getConfig().getSignMethod()); // 签名方法
//    // data.put("txnType", "00"); // 交易类型 00-默认
//    // data.put("txnSubType", "00"); // 交易子类型 默认00
//    // data.put("bizType", "000201"); // 业务类型 B2C网关支付，手机wap支付
//    //
//    // /***商户接入参数***/
//    // data.put("merId", SDKConfig.getConfig().getMerId()); // 商户号码，请改成自己申请的商户号或者open上注册得来的777商户号测试
//    // data.put("accessType", "0"); // 接入类型，商户接入固定填0，不需修改
//    //
//    // /***要调通交易以下字段必须修改***/
//    // data.put("orderId", paySerialCode); // ****商户订单号，每次发交易测试需修改为被查询的交易的订单号
//    // data.put("txnTime", txnTime); // ****订单发送时间，每次发交易测试需修改为被查询的交易的订单发送时间
//    //
//    // /**请求参数设置完毕，以下对请求参数进行签名并发送http post请求，接收同步应答报文------------->**/
//    // Map<String, String> reqData = AcpService.sign(data, SDKConfig.getConfig().getEncoding()); //
//    // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
//    //
//    // String url = SDKConfig.getConfig().getSingleQueryUrl();// 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
//    // // acpsdk.singleQueryUrl
//    // // 这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过
//    // Map<String, String> rspData = AcpService.post(reqData, url, SDKConfig.getConfig().getEncoding());
//    //
//    // LogUtil.writeErrorLog("银联交易查询接口应签报文：" + rspData);
//    //
//    // /**对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**/
//    // // 应答码规范参考open.unionpay.com帮助中心 下载 产品接口规范 《平台接入接口规范-第5部分-附录》
//    // if (!rspData.isEmpty()) {
//    // if (AcpService.validate(rspData, SDKConfig.getConfig().getEncoding())) {
//    // LogUtil.writeLog("----订单交易查询--验证签名成功");
//    // if ("00".equals(rspData.get("respCode"))) {// 如果查询交易成功
//    // // 处理被查询交易的应答码逻辑
//    // String origRespCode = rspData.get("origRespCode"); // 被查询交易的应答码
//    // if ("00".equals(origRespCode)) {
//    // return rspData;
//    // } else if ("03".equals(origRespCode) || "04".equals(origRespCode) || "05".equals(origRespCode)) {
//    // // 需再次发起交易状态查询交易
//    // LogUtil.writeLog("------需再次发起交易状态查询交易");
//    // return consumeQuery(paySerialCode, txnTime);
//    // } else {
//    // // 其他应答码为失败请排查原因
//    // LogUtil.writeLog("------其他应答码为失败请排查原因");
//    // return null;
//    // }
//    // } else {// 查询交易本身失败，或者未查到原交易，检查查询交易报文要素
//    // LogUtil.writeLog("------查询交易本身失败，或者未查到原交易，检查查询交易报文要素");
//    // return null;
//    // }
//    // } else {
//    // LogUtil.writeErrorLog("查询交易接口，验证签名失败");
//    // return null;
//    // }
//    // } else {
//    // // 未返回正确的http状态
//    // LogUtil.writeErrorLog("查询交易接口，未获取到返回报文或返回http状态码非200");
//    // return null;
//    // }
//    // }
//    //
//    // /**
//    // * 银联撤销交易接口，消费撤销仅能对当清算日的消费做，必须为全额，一般当日或第二日到账
//    // * @param response
//    // * @param paySerialCode 银联支付流水号
//    // * @param queryId 原交易查询流水号，原始消费交易的queryId
//    // * @param refundAmount 退款金额，单位是元，正常的带小数点的金额
//    // * @param txnTime 当初交易时，订单的发送时间
//    // * @param backUrl 后台通知地址（需设置为【外网】能访问 http
//    // https均可），支付成功后银联会自动将异步通知报文post到商户上送的该地址，失败的交易银联不会发送后台通知，此处指的是除去域名的相对路径，如：/amp/h5/order/unionpayBack
//    // * @return 0：成功，1：需发起交易状态查询交易确定交易状态，2：失败
//    // * @throws Exception
//    // */
//    // public static Integer consumeUndo(String paySerialCode, String queryId, BigDecimal refundAmount, String txnTime,
//    // String backUrl) throws Exception {
//    // Map<String, String> data = new HashMap<String, String>();
//    //
//    // /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
//    // data.put("version", SDKConfig.getConfig().getVersion()); // 版本号
//    // data.put("encoding", SDKConfig.getConfig().getEncoding()); // 字符集编码 可以使用UTF-8,GBK两种方式
//    // data.put("signMethod", SDKConfig.getConfig().getSignMethod()); // 签名方法
//    // data.put("txnType", "31"); // 交易类型 31-消费撤销
//    // data.put("txnSubType", "00"); // 交易子类型 默认00
//    // data.put("bizType", "000201"); // 业务类型 B2C网关支付，手机wap支付
//    // data.put("channelType", "07"); // 渠道类型，07-PC，08-手机
//    //
//    // // 生成新的订单ID，撤销交易的订单号为原始订单号+c+3位随机码
//    // String randomCode = String.valueOf(((int) (Math.random() * 1000)));
//    // while (randomCode.length() < 3) {
//    // randomCode = "0" + randomCode;
//    // }
//    // String orderId = paySerialCode + "c" + randomCode;
//    //
//    // /***商户接入参数***/
//    // data.put("merId", SDKConfig.getConfig().getMerId()); // 商户号码，请改成自己申请的商户号或者open上注册得来的777商户号测试
//    // data.put("accessType", "0"); // 接入类型，商户接入固定填0，不需修改
//    // data.put("orderId", orderId); // 商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则，重新产生，不同于原消费
//    // data.put("txnTime", DateUtil.date2Str(new Date(), "yyyyMMddHHmmss")); //
//    // 订单发送时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
//    // data.put("txnAmt", CalcUtil.mul(refundAmount, new BigDecimal("100"), 0).toString()); // 【撤销金额】，消费撤销时必须和原消费金额相同
//    // data.put("currencyCode", "156"); // 交易币种(境内商户一般是156 人民币)
//    // // data.put("reqReserved", "透传信息");
//    // //
//    // //请求方保留域，，如需使用请启用即可；透传字段（可以实现商户自定义参数的追踪）本交易的后台通知,对本交易的交易状态查询交易、对账文件中均会原样返回，商户可以按需上传，长度为1-1024个字节。出现&={}[]符号时可能导致查询接口应答报文解析失败，建议尽量只传字母数字并使用|分割，或者可以最外层做一次base64编码(base64编码之后出现的等号不会导致解析失败可以不用管)。
//    // data.put("backUrl", YmlProps.httpServerUrl + backUrl); // 后台通知地址，后台通知参数详见open.unionpay.com帮助中心 下载 产品接口规范
//    // // 网关支付产品接口规范 消费撤销交易 商户通知,其他说明同消费交易的商户通知
//    //
//    // /***要调通交易以下字段必须修改***/
//    // data.put("origQryId", queryId); // 【原始交易流水号】，原消费交易返回的的queryId，可以从消费交易后台通知接口中或者交易状态查询接口中获取
//    //
//    // /**请求参数设置完毕，以下对请求参数进行签名并发送http post请求，接收同步应答报文**/
//    // Map<String, String> reqData = AcpService.sign(data, SDKConfig.getConfig().getEncoding()); //
//    // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
//    // String reqUrl = SDKConfig.getConfig().getBackRequestUrl();// 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
//    // // acpsdk.backTransUrl
//    //
//    // Map<String, String> rspData = AcpService.post(reqData, reqUrl, SDKConfig.getConfig().getEncoding()); //
//    // 发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过
//    //
//    // LogUtil.writeErrorLog("银联撤销交易接口应签报文：" + rspData);
//    //
//    // // 应答码规范参考open.unionpay.com帮助中心 下载 产品接口规范 《平台接入接口规范-第5部分-附录》
//    // if (!rspData.isEmpty()) {
//    // if (AcpService.validate(rspData, SDKConfig.getConfig().getEncoding())) {
//    // LogUtil.writeLog("银联撤销交易接口验证签名成功");
//    // String respCode = rspData.get("respCode");
//    // if ("00".equals(respCode)) {
//    // // 交易已受理(不代表交易已成功），等待接收后台通知确定交易成功，也可以主动发起 查询交易确定交易状态。
//    // return 0;
//    // } else if ("03".equals(respCode) || "04".equals(respCode) || "05".equals(respCode)) {
//    // // 后续需发起交易状态查询交易确定交易状态。
//    // LogUtil.writeLog("------银联撤销交易接口返回的状态码为03/04/05，需再次发起交易状态查询交易");
//    // return 1;
//    // } else {
//    // // 其他应答码为失败请排查原因
//    // LogUtil.writeLog("------银联撤销接口返回的状态码为其他应答码失败，请排查原因");
//    // return 2;
//    // }
//    // } else {
//    // LogUtil.writeErrorLog("验证签名失败");
//    // return 2;
//    // }
//    // } else {
//    // // 未返回正确的http状态
//    // LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");
//    // return 2;
//    // }
//    // }
//    //
//    // /**
//    // * 银联退款接口
//    // * @param response
//    // * @param paySerialCode 银联支付流水号
//    // * @param queryId 原交易查询流水号，原始消费交易的queryId
//    // * @param refundAmount 退款金额，单位是元，正常的带小数点的金额
//    // * @param txnTime 当初交易时，订单的发送时间
//    // * @param backUrl 后台通知地址（需设置为【外网】能访问 http
//    // https均可），支付成功后银联会自动将异步通知报文post到商户上送的该地址，失败的交易银联不会发送后台通知，此处指的是除去域名的相对路径，如：/amp/h5/order/unionpayBack
//    // * @return 0：成功，1：需发起交易状态查询交易确定交易状态，2：失败
//    // * @throws Exception
//    // */
//    // public static Integer consumeRefund(String paySerialCode, String queryId, BigDecimal refundAmount, String
//    // txnTime,
//    // String backUrl) throws Exception {
//    // Map<String, String> data = new HashMap<String, String>();
//    //
//    // /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
//    // data.put("version", SDKConfig.getConfig().getVersion()); // 版本号
//    // data.put("encoding", SDKConfig.getConfig().getEncoding()); // 字符集编码 可以使用UTF-8,GBK两种方式
//    // data.put("signMethod", SDKConfig.getConfig().getSignMethod()); // 签名方法
//    // data.put("txnType", "04"); // 交易类型 04-退货
//    // data.put("txnSubType", "00"); // 交易子类型 默认00
//    // data.put("bizType", "000201"); // 业务类型 B2C网关支付，手机wap支付
//    // data.put("channelType", "07"); // 渠道类型，07-PC，08-手机
//    //
//    // // 生成新的订单ID，退货交易的订单号为原始订单号+t+3位随机码
//    // String randomCode = String.valueOf(((int) (Math.random() * 1000)));
//    // while (randomCode.length() < 3) {
//    // randomCode = "0" + randomCode;
//    // }
//    // String orderId = paySerialCode + "t" + randomCode;
//    //
//    // /***商户接入参数***/
//    // data.put("merId", SDKConfig.getConfig().getMerId()); // 商户号码，请改成自己申请的商户号或者open上注册得来的777商户号测试
//    // data.put("accessType", "0"); // 接入类型，商户接入固定填0，不需修改
//    // data.put("orderId", orderId); // 商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则，重新产生，不同于原消费
//    // data.put("txnTime", DateUtil.date2Str(new Date(), "yyyyMMddHHmmss")); //
//    // 订单发送时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
//    // data.put("currencyCode", "156"); // 交易币种（境内商户一般是156 人民币）
//    // data.put("txnAmt", CalcUtil.mul(refundAmount, new BigDecimal("100"), 0).toString()); //
//    // ****退货金额，单位分，不要带小数点。退货金额小于等于原消费金额，当小于的时候可以多次退货至退货累计金额等于原消费金额
//    // // data.put("reqReserved", "透传信息");
//    // //
//    // //请求方保留域，如需使用请启用即可；透传字段（可以实现商户自定义参数的追踪）本交易的后台通知,对本交易的交易状态查询交易、对账文件中均会原样返回，商户可以按需上传，长度为1-1024个字节。出现&={}[]符号时可能导致查询接口应答报文解析失败，建议尽量只传字母数字并使用|分割，或者可以最外层做一次base64编码(base64编码之后出现的等号不会导致解析失败可以不用管)。
//    // data.put("backUrl", YmlProps.httpServerUrl + backUrl); // 后台通知地址，后台通知参数详见open.unionpay.com帮助中心 下载 产品接口规范
//    // // 网关支付产品接口规范 退货交易 商户通知,其他说明同消费交易的后台通知
//    //
//    // /***要调通交易以下字段必须修改***/
//    // data.put("origQryId", queryId); // ****原消费交易返回的的queryId，可以从消费交易后台通知接口中或者交易状态查询接口中获取
//    //
//    // /**请求参数设置完毕，以下对请求参数进行签名并发送http post请求，接收同步应答报文------------->**/
//    // Map<String, String> reqData = AcpService.sign(data, SDKConfig.getConfig().getEncoding()); //
//    // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
//    // String url = SDKConfig.getConfig().getBackRequestUrl(); // 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
//    // // acpsdk.backTransUrl
//    //
//    // Map<String, String> rspData = AcpService.post(reqData, url, SDKConfig.getConfig().getEncoding()); //
//    // 这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过
//    //
//    // LogUtil.writeErrorLog("银联退款接口应签报文：" + rspData);
//    //
//    // /**对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**/
//    // // 应答码规范参考open.unionpay.com帮助中心 下载 产品接口规范 《平台接入接口规范-第5部分-附录》
//    // if (!rspData.isEmpty()) {
//    // if (AcpService.validate(rspData, SDKConfig.getConfig().getEncoding())) {
//    // LogUtil.writeLog("银联退款接口验证签名成功");
//    // String respCode = rspData.get("respCode");
//    // if ("00".equals(respCode)) {
//    // // 交易已受理，等待接收后台通知更新订单状态,也可以主动发起 查询交易确定交易状态。
//    // LogUtil.writeLog("------银联退款接口返回的状态码为00，交易已受理");
//    // return 0;
//    // } else if ("03".equals(respCode) || "04".equals(respCode) || "05".equals(respCode)) {
//    // // 后续需发起交易状态查询交易确定交易状态
//    // LogUtil.writeLog("------银联退款接口返回的状态码为03/04/05，需再次发起交易状态查询交易");
//    // return 1;
//    // } else {
//    // // 其他应答码为失败请排查原因
//    // LogUtil.writeLog("------银联退款接口返回的状态码为其他应答码失败，请排查原因");
//    // return 2;
//    // }
//    // } else {
//    // LogUtil.writeErrorLog("银联退款接口验证签名失败");
//    // return 2;
//    // }
//    // } else {
//    // // 未返回正确的http状态
//    // LogUtil.writeErrorLog("银联退款接口未获取到返回报文或返回http状态码非200");
//    // return 2;
//    // }
//    // }
//
//}
